//
//  JCPopView.swift
//  JCPopView
//
//  Created by 吴金成 on 16/10/9.
//  Copyright © 2016年 吴金成. All rights reserved.
//

import UIKit

//关闭按钮的位置
enum ButtonPositionType {
    
    case none
    case left
    case right
}
//蒙版的背景色
enum ShadeBackgroundType {

    case gradient //渐变色
    case solid //固定色
}

private let kShadeViewShowTime: TimeInterval = 0.5
private let kAnimationTime1: TimeInterval = 0.3
private let kAnimationTime2: TimeInterval = 0.2
private let kAnimationTime3: TimeInterval = 0.3
private let kDefaultCloseButtonPadding: CGFloat = 17.0

class JCPopView: NSObject {
    
    //点击蒙版是否关闭视图，默认 true
    var tapOutsideToDismiss: Bool = true
    //关闭按钮的位置，默认右上角
    var closeButtonType: ButtonPositionType = .right
    //蒙版的背景色，默认固定色
    var shadeBackgroundType: ShadeBackgroundType = .solid
    //视图消失回调
    var closeCompletion: (()->())?
    
    //创建单例
    class func share() -> JCPopView {
        
        struct instance {
            
            static let share = JCPopView()
        }
        return instance.share
    }
    
    //MARK:  弹出视图
    public func showView(presentView: UIView, animated: Bool, complete: (()->())? )
    {
        let padding: CGFloat = 17.0
        var containerViewRect = presentView.bounds.insetBy(dx: -padding, dy: -padding)
        containerViewRect.origin.x = (window.bounds.width - containerViewRect.width)/2
        containerViewRect.origin.y = (window.bounds.height - containerViewRect.height)/2
        
        //设置视图 Frame并添加到容器视图上
        containerView.frame = containerViewRect
        presentView.frame.origin = CGPoint(x: padding, y: padding)
        presentedView = presentView
        containerView.insertSubview(presentedView!, at: 0)
        
        //设置关闭按钮的位置
        setCloseBtnType(type: closeButtonType)
        
        //弹出动画
        DispatchQueue.main.async {
            
            self.window.makeKeyAndVisible()
            
            if animated == true {
                
                self.viewController.shadeView.alpha = 0
                UIView.animate(withDuration: kShadeViewShowTime, animations: {
                    self.viewController.shadeView.alpha = 1
                })
                
                self.containerView.alpha = 0
                self.containerView.layer.shouldRasterize = true
                self.containerView.transform = CGAffineTransform.init(scaleX: 0, y: 0)
                
                UIView.animate(withDuration: kAnimationTime1, animations: {
                    self.containerView.alpha = 1
                    self.containerView.transform = CGAffineTransform.init(scaleX: 1.05, y: 1.05)
                    
                    }, completion: { (finished) in
                        
                        UIView.animate(withDuration: kAnimationTime2, animations: {
                            
                             self.containerView.transform = CGAffineTransform.init(scaleX: 0.95, y: 0.95)
                            
                            }, completion: { (finished) in
                                UIView.animate(withDuration: kAnimationTime3, delay: 0, options: .curveEaseInOut, animations: {
                                    
                                     self.containerView.transform = CGAffineTransform.identity
                                    
                                    }, completion: { (finished) in
                                        
                                        self.containerView.layer.shouldRasterize = false
                                        complete?()
                                })
                        })
                })
            }
        }
    }
    
    //设置关闭按钮的位置
    private func setCloseBtnType(type: ButtonPositionType) -> () {
        
        var closeFrame = closeButton.frame
        
        switch type {
            
        case .none:
            
            closeButton.isHidden = true
        case .left:
            
            closeButton.isHidden = false
            closeFrame.origin.x = 0
        case .right:
            
            closeButton.isHidden = false
            closeFrame.origin.x = round(containerView.frame.width - kDefaultCloseButtonPadding - closeFrame.width/2)
            
        }
        closeButton.frame = closeFrame
    }
    
    /// 关闭视图
    public func closeView(complete: (()->())?) {
    
        hideAnimated(animated: true, completion: complete)
    }
    
    @objc private func close() -> () {
        
        hideAnimated(animated: true, completion: nil)
    }
    
    func hideAnimated(animated: Bool, completion: (()->())?) -> () {
        
        if animated == false {
            
            cleanUp()
            completion?()
            closeCompletion?()
            return
        }
        
        DispatchQueue.main.async {
            
            UIView.animate(withDuration: kShadeViewShowTime, animations: {
                self.viewController.shadeView.alpha = 0
            })
            self.containerView.layer.shouldRasterize = true
            
            UIView.animate(withDuration: kAnimationTime2, animations: {
                
                self.containerView.transform = CGAffineTransform.init(scaleX: 1.05, y: 1.05)
                
                }, completion: { (finished) in
                    
                    UIView.animate(withDuration: kAnimationTime1, delay: 0, options: .curveEaseOut, animations: {
                        
                        self.containerView.alpha = 0
                        self.containerView.transform = CGAffineTransform.identity
                        
                        }, completion: { (finished) in
                            
                            self.cleanUp()
                            completion?()
                            self.closeCompletion?()
                    })
            })
        }
    }
    
    //清除视图
    private func cleanUp() -> () {
        
        UIApplication.shared.delegate?.window??.makeKeyAndVisible()
        presentedView?.removeFromSuperview()
        presentedView = nil
    }
    
    //MARK: 懒加载
    private var presentedView: UIView?
    
    private lazy var window: UIWindow = {
        let win = UIWindow(frame: UIScreen.main.bounds)
        win.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        win.isOpaque = false
        win.rootViewController = self.viewController
        return win
    }()
    
    private lazy var viewController: JCViewController = {
        let vc = JCViewController()
        vc.view.addSubview(self.containerView)
        return vc
    }()
    
    private lazy var containerView: UIView = {
        let view = UIView()
        view.autoresizingMask = [.flexibleLeftMargin, .flexibleTopMargin, .flexibleRightMargin, .flexibleBottomMargin]
        view.layer.rasterizationScale = UIScreen.main.scale
        view.addSubview(self.closeButton)
        return view
    }()
    
    private lazy var closeButton: UIButton = {
        
        let btn = UIButton(type: UIButtonType.custom)
        btn.frame = CGRect(x: 0, y: 0, width: 32, height: 32)
        btn.setBackgroundImage(UIImage(named: "close"), for: UIControlState.normal)
        btn.addTarget(self, action: #selector(close), for: .touchUpInside)
        return btn
    }()
}

//MARK: - 自定义控制器
private class JCViewController: UIViewController {
    
    override func loadView() {
        view = UIView(frame: UIScreen.main.bounds)
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.backgroundColor = UIColor.clear
        view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        view.addSubview(shadeView)
    }
    
    lazy var shadeView: JCShadeView = {
        
        let view = JCShadeView()
        view.frame = UIScreen.main.bounds
        view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        view.isOpaque = false
        return view
    }()
}
//MARK: - 自定义蒙板
private class JCShadeView: UIView {
    
    override func draw(_ rect: CGRect) {
        
        guard let context = UIGraphicsGetCurrentContext() else {
            return
        }
        
        if JCPopView.share().shadeBackgroundType == .solid {
            UIColor(white: 0.0, alpha: 0.25).set()
            context.fill(bounds)
        } else {
            context.saveGState()
            
            let gradLoactionsNum: size_t = 2
            let gradLocations: [CGFloat] = [0.0, 1.0]
            let gradColors: [CGFloat] = [0, 0, 0, 0.3, 0, 0, 0, 0.8]
            let colorSpace = CGColorSpaceCreateDeviceRGB()
            let gradient = CGGradient(colorSpace: colorSpace, colorComponents: gradColors, locations: gradLocations, count: gradLoactionsNum)
            
            //            CGColorSpaceRelease(colorSpace);
            //            colorSpace = nil
            
            let gradCenter = CGPoint(x: bounds.midX, y: round(bounds.midY))
            let gradRadius = max(bounds.width, bounds.height)
            context.drawRadialGradient(gradient!, startCenter: gradCenter, startRadius: 0, endCenter: gradCenter, endRadius: gradRadius, options: .drawsBeforeStartLocation)
            
            //            CGGradientRelease(gradient!)
            //            gradient = NULL
            
            context.restoreGState()
        }
    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        
        if JCPopView.share().tapOutsideToDismiss == true {
            
            JCPopView.share().hideAnimated(animated: true, completion: nil)
        }
    }
}


